import { RouteMeta, RouteRecordRaw } from 'vue-router'
import { Module } from 'vuex'
import { State as RootState } from '../index'
import {
  FlowPost,
  FlowPostGroup,
  flow,
  getUserData,
  UserResItem
} from '@/api/flow'
import { createRoute } from '@/router/routes'

export interface State {
  routes: RouteRecordRaw[]
  staticRoutes: RouteRecordRaw[]
  asyncRoutes: RouteRecordRaw[]
  flows: FlowPostGroup[]
  users: any[]
}

export enum MutationTypes {
  INIT_ROUTERS = 'INIT_ROUTERS',
  SET_ROUTERS = 'SET_ROUTERS',
  SET_FORMS = 'SET_FORMS',
  INIT_USERS = 'INIT_USERS'
}

type AugmentedActionContext = {
  // eslint-disable-next-line
  commit(key: MutationTypes, p?: any): void
}

function hasPermission(roles: string[], route: RouteRecordRaw): boolean {
  if (!route || !route.meta || !route.meta.roles) return true
  return roles.some(role =>
    ((route.meta as RouteMeta).roles as string[]).includes(role)
  )
}

export function filterAsyncRoutes(
  routes: RouteRecordRaw[],
  roles: string[]
): RouteRecordRaw[] {
  const res: RouteRecordRaw[] = []

  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

const state = (): State => ({
  routes: [],
  staticRoutes: [],
  asyncRoutes: [],
  flows: [],
  users: []
})

const mutations = {
  [MutationTypes.INIT_ROUTERS]: (
    state: State,
    payload: Array<RouteRecordRaw>
  ): void => {
    state.routes = payload
    state.staticRoutes = payload
  },
  [MutationTypes.SET_ROUTERS]: (
    state: State,
    payload: Array<RouteRecordRaw>
  ): void => {
    state.asyncRoutes = [...new Set([...state.asyncRoutes, ...payload])]
    state.routes = [...state.staticRoutes, ...state.asyncRoutes]
  },
  [MutationTypes.SET_FORMS]: (state: State, payload: FlowPostGroup[]): void => {
    state.flows = payload
  },
  [MutationTypes.INIT_USERS]: (state: State, payload: any[]): void => {
    state.users = payload
  }
}

const actions = {
  initRouters: (
    ctx: AugmentedActionContext,
    routes: Array<RouteRecordRaw>
  ): void => {
    ctx.commit(MutationTypes.INIT_ROUTERS, routes)
  },
  getFlows: async (ctx: AugmentedActionContext): Promise<RouteRecordRaw[]> => {
    try {
      const res = await flow()
      // const res = await pywebview.api.list_flow()
      const routes: RouteRecordRaw[] = []
      res?.forEach(item => {
        item.flows.forEach(f => {
          routes.push(createRoute(f))
        })
      })

      ctx.commit(MutationTypes.SET_FORMS, res)
      ctx.commit(MutationTypes.SET_ROUTERS, routes)
      return Promise.resolve(routes)
    } catch (err) {
      console.log(err)
      throw err
    }
  },
  initUsers: (ctx: AugmentedActionContext): void => {
    getUserData()
      .then(res => {
        const result = res
          .sort((a, b) => b['序号'] - a['序号'])
          .map((item: UserResItem) => {
            return {
              name: item['用户名'],
              pwd: item['密码'],
              value: item['显示名称']
            }
          })
        ctx.commit(MutationTypes.INIT_USERS, result)
      })
      .catch(err => {
        console.log(err)
      })
  }
}

const ModuleItem: Module<State, RootState> = {
  namespaced: true,
  state,
  mutations,
  actions
}

export default ModuleItem
